package com.ruoyi.system.service.impl;


import com.ruoyi.common.core.constant.UserConstants;
import com.ruoyi.common.core.exception.ServiceException;
import com.ruoyi.common.core.text.Convert;
import com.ruoyi.common.core.utils.SpringUtils;
import com.ruoyi.common.core.utils.StringUtils;
import com.ruoyi.common.security.utils.SecurityUtils;
import com.ruoyi.system.api.domain.SysCompany;
import com.ruoyi.system.api.domain.SysRole;
import com.ruoyi.system.api.domain.SysUser;
import com.ruoyi.system.domain.vo.TreeSelect;
import com.ruoyi.system.mapper.SysCompanyMapper;
import com.ruoyi.system.mapper.SysRoleMapper;
import com.ruoyi.system.service.ISysCompanyService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 公司管理 服务实现
 *
 * @author ruoyi
 */
@Service
public class SysCompanyServiceImpl implements ISysCompanyService {
    @Autowired
    private SysCompanyMapper companyMapper;

    @Autowired
    private SysRoleMapper roleMapper;

    /**
     * 查询公司管理数据
     *
     * @param company 公司信息
     * @return 公司信息集合
     */
    @Override
    public List<SysCompany> selectCompanyList(SysCompany company) {
        return companyMapper.selectCompanyList(company);
    }

    /**
     * 构建前端所需要树结构
     *
     * @param companys 公司列表
     * @return 树结构列表
     */
    @Override
    public List<SysCompany> buildCompanyTree(List<SysCompany> companys) {
        List<SysCompany> returnList = new ArrayList<SysCompany>();
        List<Long> tempList = new ArrayList<Long>();
        for (SysCompany company : companys) {
            tempList.add(company.getCompanyId());
        }
        for (SysCompany company : companys) {
            // 如果是顶级节点, 遍历该父节点的所有子节点
            if (!tempList.contains(company.getParentId())) {
                recursionFn(companys, company);
                returnList.add(company);
            }
        }
        if (returnList.isEmpty()) {
            returnList = companys;
        }
        return returnList;
    }

    /**
     * 构建前端所需要下拉树结构
     *
     * @param companys 公司列表
     * @return 下拉树结构列表
     */
    @Override
    public List<TreeSelect> buildCompanyTreeSelect(List<SysCompany> companys) {
        List<SysCompany> companyTrees = buildCompanyTree(companys);
        return companyTrees.stream().map(TreeSelect::new).collect(Collectors.toList());
    }

    /**
     * 根据角色ID查询公司树信息
     *
     * @param roleId 角色ID
     * @return 选中公司列表
     */
    @Override
    public List<Long> selectCompanyListByRoleId(Long roleId) {
        SysRole role = roleMapper.selectRoleById(roleId);
        return companyMapper.selectCompanyListByRoleId(roleId, role.isCompanyCheckStrictly());
    }

    /**
     * 根据公司ID查询信息
     *
     * @param companyId 公司ID
     * @return 公司信息
     */
    @Override
    public SysCompany selectCompanyById(Long companyId) {
        return companyMapper.selectCompanyById(companyId);
    }

    /**
     * 根据ID查询所有子公司（正常状态）
     *
     * @param companyId 公司ID
     * @return 子公司数
     */
    @Override
    public int selectNormalChildrenCompanyById(Long companyId) {
        return companyMapper.selectNormalChildrenCompanyById(companyId);
    }

    /**
     * 是否存在子节点
     *
     * @param companyId 公司ID
     * @return 结果
     */
    @Override
    public boolean hasChildByCompanyId(Long companyId) {
        int result = companyMapper.hasChildByCompanyId(companyId);
        return result > 0 ? true : false;
    }

    /**
     * 查询公司是否存在用户
     *
     * @param companyId 公司ID
     * @return 结果 true 存在 false 不存在
     */
    @Override
    public boolean checkCompanyExistUser(Long companyId) {
        int result = companyMapper.checkCompanyExistUser(companyId);
        return result > 0 ? true : false;
    }

    /**
     * 校验公司名称是否唯一
     *
     * @param company 公司信息
     * @return 结果
     */
    @Override
    public String checkCompanyNameUnique(SysCompany company) {
        Long companyId = StringUtils.isNull(company.getCompanyId()) ? -1L : company.getCompanyId();
        SysCompany info = companyMapper.checkCompanyNameUnique(company.getCompanyName(), company.getParentId());
        if (StringUtils.isNotNull(info) && info.getCompanyId().longValue() != companyId.longValue()) {
            return UserConstants.NOT_UNIQUE;
        }
        return UserConstants.UNIQUE;
    }

    /**
     * 校验公司是否有数据权限
     *
     * @param companyId 公司id
     */
    @Override
    public void checkCompanyDataScope(Long companyId) {
        if (!SysUser.isAdmin(SecurityUtils.getUserId())) {
            SysCompany company = new SysCompany();
            company.setCompanyId(companyId);
            List<SysCompany> companys = SpringUtils.getAopProxy(this).selectCompanyList(company);
            if (StringUtils.isEmpty(companys)) {
                throw new ServiceException("没有权限访问公司数据！");
            }
        }
    }

    /**
     * 新增保存公司信息
     *
     * @param company 公司信息
     * @return 结果
     */
    @Override
    public int insertCompany(SysCompany company) {
        SysCompany info = companyMapper.selectCompanyById(company.getParentId());
        // 如果父节点不为正常状态,则不允许新增子节点
        if (!UserConstants.DEPT_NORMAL.equals(info.getStatus())) {
            throw new ServiceException("公司停用，不允许新增");
        }
        company.setAncestors(info.getAncestors() + "," + company.getParentId());
        return companyMapper.insertCompany(company);
    }

    /**
     * 修改保存公司信息
     *
     * @param company 公司信息
     * @return 结果
     */
    @Override
    public int updateCompany(SysCompany company) {
        SysCompany newParentSysCompany = companyMapper.selectCompanyById(company.getParentId());
        SysCompany oldSysCompany = companyMapper.selectCompanyById(company.getCompanyId());
        if (StringUtils.isNotNull(newParentSysCompany) && StringUtils.isNotNull(oldSysCompany)) {
            String newAncestors = newParentSysCompany.getAncestors() + "," + newParentSysCompany.getCompanyId();
            String oldAncestors = oldSysCompany.getAncestors();
            company.setAncestors(newAncestors);
            updateSysCompanyChildren(company.getCompanyId(), newAncestors, oldAncestors);
        }
        int result = companyMapper.updateCompany(company);
        if (UserConstants.DEPT_NORMAL.equals(company.getStatus()) && StringUtils.isNotEmpty(company.getAncestors())
                && !StringUtils.equals("0", company.getAncestors())) {
            // 如果该公司是启用状态，则启用该公司的所有上级公司
            updateParentSysCompanyStatusNormal(company);
        }
        return result;
    }

    /**
     * 修改该公司的父级公司状态
     *
     * @param company 当前公司
     */
    private void updateParentSysCompanyStatusNormal(SysCompany company) {
        String ancestors = company.getAncestors();
        Long[] companyIds = Convert.toLongArray(ancestors);
        companyMapper.updateCompanyStatusNormal(companyIds);
    }

    /**
     * 修改子元素关系
     *
     * @param companyId    被修改的公司ID
     * @param newAncestors 新的父ID集合
     * @param oldAncestors 旧的父ID集合
     */
    public void updateSysCompanyChildren(Long companyId, String newAncestors, String oldAncestors) {
        List<SysCompany> children = companyMapper.selectChildrenCompanyById(companyId);
        for (SysCompany child : children) {
            child.setAncestors(child.getAncestors().replaceFirst(oldAncestors, newAncestors));
        }
        if (children.size() > 0) {
            companyMapper.updateCompanyChildren(children);
        }
    }

    /**
     * 删除公司管理信息
     *
     * @param companyId 公司ID
     * @return 结果
     */
    @Override
    public int deleteCompanyById(Long companyId) {
        return companyMapper.deleteCompanyById(companyId);
    }

    /**
     * 递归列表
     */
    private void recursionFn(List<SysCompany> list, SysCompany t) {
        // 得到子节点列表
        List<SysCompany> childList = getChildList(list, t);
        t.setChildren(childList);
        for (SysCompany tChild : childList) {
            if (hasChild(list, tChild)) {
                recursionFn(list, tChild);
            }
        }
    }

    /**
     * 得到子节点列表
     */
    private List<SysCompany> getChildList(List<SysCompany> list, SysCompany t) {
        List<SysCompany> tlist = new ArrayList<SysCompany>();
        Iterator<SysCompany> it = list.iterator();
        while (it.hasNext()) {
            SysCompany n = (SysCompany) it.next();
            if (StringUtils.isNotNull(n.getParentId()) && n.getParentId().longValue() == t.getCompanyId().longValue()) {
                tlist.add(n);
            }
        }
        return tlist;
    }

    /**
     * 判断是否有子节点
     */
    private boolean hasChild(List<SysCompany> list, SysCompany t) {
        return getChildList(list, t).size() > 0 ? true : false;
    }
}
